/*
 * Copyright (c) 2009 Charles S. Wilson
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a 
 * copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the 
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included 
 * in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
 * OTHER DEALINGS IN THE SOFTWARE.
 */
#ifndef RUN2_CONFPARSE_H
#define RUN2_CONFPARSE_H

#include <libxml/globals.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlmemory.h>

#include "confdata.h"

extern const char * RUN2_XSD;

typedef enum _parse_state {
    RUN2_XMLPARSE_UNINITIALIZED = -2,
    RUN2_XMLPARSE_UNKNOWN_STATE = -1,
    RUN2_XMLPARSE_START,
    RUN2_XMLPARSE_INSIDE_RUN2_CONFIG,
    RUN2_XMLPARSE_INSIDE_SELF_OPTIONS,
    RUN2_XMLPARSE_INSIDE_SELF_OPTIONS_ARG,
    RUN2_XMLPARSE_INSIDE_GLOBAL,
    RUN2_XMLPARSE_INSIDE_GLOBAL_ENVIRONMENT,
    RUN2_XMLPARSE_INSIDE_GLOBAL_ENVIRONMENT_PREPEND,
    RUN2_XMLPARSE_INSIDE_GLOBAL_ENVIRONMENT_APPEND,
    RUN2_XMLPARSE_INSIDE_GLOBAL_ENVIRONMENT_SET,
    RUN2_XMLPARSE_INSIDE_GLOBAL_AFTER_ENVIRONMENT,
    RUN2_XMLPARSE_INSIDE_GLOBAL_TARGET,
    RUN2_XMLPARSE_INSIDE_GLOBAL_TARGET_ARG,
    RUN2_XMLPARSE_INSIDE_GLOBAL_AFTER_TARGET,
    RUN2_XMLPARSE_INSIDE_GDI,
    RUN2_XMLPARSE_INSIDE_GDI_ENVIRONMENT,
    RUN2_XMLPARSE_INSIDE_GDI_ENVIRONMENT_PREPEND,
    RUN2_XMLPARSE_INSIDE_GDI_ENVIRONMENT_APPEND,
    RUN2_XMLPARSE_INSIDE_GDI_ENVIRONMENT_SET,
    RUN2_XMLPARSE_INSIDE_GDI_AFTER_ENVIRONMENT,
    RUN2_XMLPARSE_INSIDE_GDI_TARGET,
    RUN2_XMLPARSE_INSIDE_GDI_TARGET_ARG,
    RUN2_XMLPARSE_INSIDE_GDI_AFTER_TARGET,
    RUN2_XMLPARSE_INSIDE_X11,
    RUN2_XMLPARSE_INSIDE_X11_ENVIRONMENT,
    RUN2_XMLPARSE_INSIDE_X11_ENVIRONMENT_PREPEND,
    RUN2_XMLPARSE_INSIDE_X11_ENVIRONMENT_APPEND,
    RUN2_XMLPARSE_INSIDE_X11_ENVIRONMENT_SET,
    RUN2_XMLPARSE_INSIDE_X11_AFTER_ENVIRONMENT,
    RUN2_XMLPARSE_INSIDE_X11_TARGET,
    RUN2_XMLPARSE_INSIDE_X11_TARGET_ARG,
    RUN2_XMLPARSE_INSIDE_X11_AFTER_TARGET,
    RUN2_XMLPARSE_FINISH
} parse_state_t;

typedef struct _string_buffer {
    xmlChar *buf;
    size_t   buf_sz;
    size_t   buf_used;
} string_buffer_t;

typedef struct _conf_parser_state {
    parse_state_t    state;
    parse_state_t    prev_state;
    unsigned int     unknown_depth;
    cdsl_dlist_t    *stack;
    run2_confdata_t *data;
} conf_parser_state_t;

typedef struct _element_and_state {
    void          *element;
    parse_state_t  state;
} element_and_state_t;



const char * run2_parse_state_name (parse_state_t state);
char * run2_parse_state_description (conf_parser_state_t* state);

string_buffer_t *run2_xml_new_string_buffer (void);
void run2_xml_destroy_string_buffer (string_buffer_t *arg);

element_and_state_t *run2_new_element_and_state (void *element,
                                                 parse_state_t state);
void run2_destroy_element_and_state (void *arg);
void   run2_xml_stackpush (conf_parser_state_t* state, void * newdata);
void * run2_xml_stackpop  (conf_parser_state_t* state);
void   run2_xml_stackdestroy (conf_parser_state_t* state);

void run2_xml_warning(void *ctx, const char *msg, ...);
void run2_xml_error(void *ctx, const char *msg, ...);
void run2_xml_fatal_error(void *ctx, const char *msg, ...);

void run2_xml_startdocument(void *ctx);
void run2_xml_enddocument  (void *ctx);
void run2_xml_characters   (void           *ctx,
                            const xmlChar  *ch,
                            int             len);
void run2_xml_startelementns(
    void           *ctx,
    const xmlChar  *localname,
    const xmlChar  *prefix,
    const xmlChar  *URI,
    int             nb_namespaces,
    const xmlChar **namespaces,
    int             nb_attributes,
    int             nb_defaulted,
    const xmlChar **attributes);
void run2_xml_endelementns(
    void          *ctx,
    const xmlChar *localname,
    const xmlChar *prefix,
    const xmlChar *URI);
xmlEntityPtr run2_xml_getentity(void          *ctx,
                                const xmlChar *name);

#endif /* RUN2_CONFPARSE_H */

